package deanandjames.movement;

import javax.vecmath.Point2d;
import javax.vecmath.Vector2d;

public class MovementManager {
	private static final double MAX_SPEED = 2.0;
	private static final double ROTATION_AMOUNT = 0.05;
	private final boolean isPoweredObject;
	private final int maxHeight;
	private final int maxWidth;
	private final Moveable moveable;

	public MovementManager(Moveable moveable, int maxWidth, int maxHeight, boolean isPoweredObject) {
		this.moveable = moveable;
		this.maxWidth = maxWidth;
		this.maxHeight = maxHeight;
		this.isPoweredObject = isPoweredObject;
	}

	public void accellerate() {
		double newSpeed = moveable.getSpeed() + 1;
		moveable.setSpeed(newSpeed > MAX_SPEED ? MAX_SPEED : newSpeed);
	}

	public void decellerate() {
		double newSpeed = moveable.getSpeed() - 1;
		moveable.setSpeed(newSpeed < 0 ? 0 : newSpeed);
	}

	public void drift() {
		moveable.setHeading(moveable.getHeading() + Math.random());
		moveable.setSpeed(10.0 * Math.random());

		moveAndScreenWrap();
	}

	private Point2d move() {
		Point2d position = moveable.getPosition();
		double speed = moveable.getSpeed();
		double heading = moveable.getHeading();
		Vector2d headingVector = new Vector2d(Math.cos(heading), Math.sin(heading));

		if (speed > 0) {
			if (isPoweredObject) {
				double direction = moveable.getDirection();

				// TODO: This should be scaled by previous speed
				Vector2d currentDirection = new Vector2d(Math.cos(direction), Math.sin(direction));

				currentDirection.add(headingVector);
				double newDirection = currentDirection.angle(new Vector2d(1, 0));
				moveable.setDirection(newDirection);

				currentDirection.normalize();
				currentDirection.scale(speed);

				position.add(currentDirection);
			} else {
				headingVector.scale(speed);

				position.add(headingVector);
			}
		}
		return position;
	}

	public void moveAndNeverWrap() {
		Point2d position = moveable.getPosition();

		if (position.x > maxWidth || position.x < 0 || position.y > maxHeight || position.y < 0) {
			moveable.setDisabled();
		} else {
			move();
		}
	}

	public void moveAndScreenWrap() {
		Point2d position = move();

		if (position.x > maxWidth) {
			position.x = 0;
		}
		if (position.x < 0) {
			position.x = maxWidth;
		}
		if (position.y > maxHeight) {
			position.y = 0;
		}
		if (position.y < 0) {
			position.y = maxHeight;
		}
	}

	public void turnLeft() {
		moveable.setHeading(moveable.getHeading() - ROTATION_AMOUNT);
	}

	public void turnRight() {
		moveable.setHeading(moveable.getHeading() + ROTATION_AMOUNT);
	}
}
